# -*- coding: utf-8 -*-
# @Time: 2021/11/11 13:20
# @Author: lijinxi
# @File    : online_switch.py
# @desc
import numpy as np

from service_placement_request_schedule import *

no_switch_delay = [0]
switch_delay = dict()
index = []


def cal_switch_delay(last_service, current_service, sprs: ServicePlacementRequestSchedule):
    switch_delay = 0
    for i in range(sprs.number_requests):
        for j in range(sprs.type_network_functions):
            if sprs.network_function_matrix[i][j] == 1:
                if last_service[i, j] @ current_service[i, j] == 0:
                    switch_delay += sprs.computing_capacity_vector[j]
    return switch_delay * 0.05


def compare(last_service, current_service, sprs: ServicePlacementRequestSchedule):
    flag = True
    for i in range(sprs.number_requests):
        for j in range(sprs.type_network_functions):
            for k in range(sprs.number_edge_servers):
                if last_service[i, j, k] != current_service[i, j, k]:
                    flag = False
                    break
    return flag


def online_switch(beta=5):
    sprs = ServicePlacementRequestSchedule()
    sprs.initialize_requests()
    t = 1
    switch_t: int = 1  # 切换时间
    # 最开始的服务放置，初始化为0或随机值
    last_service_placement = np.zeros(
        shape=(sprs.number_requests, sprs.type_network_functions, sprs.number_access_points), dtype=np.int8)
    sprs.update_trace(time_slot=0)
    fixed_service_placement, fixed_request_schedule, delay, i = sprs.iteration_algorithm()
    index.append(i)
    switch_service_placement = fixed_service_placement
    no_switch_delay.append(delay)
    switch_delay[switch_t] = cal_switch_delay(last_service_placement, switch_service_placement, sprs)
    for t in range(1, 21):  # 20个时隙
        print("==" * 60)
        print(t)
        if switch_delay[switch_t] <= sum(no_switch_delay[switch_t: t - 1 + 1]) / beta:
            print("switch")
            sprs.update_trace(time_slot=t - 1)
            fixed_service_placement, fixed_request_schedule, delay, i = sprs.iteration_algorithm()
            index.append(i)
            no_switch_delay.append(delay)
            if not compare(fixed_service_placement, switch_service_placement, sprs):
                switch_t = t
                last_service_placement = switch_service_placement
                switch_service_placement = fixed_service_placement
                switch_delay[switch_t] = cal_switch_delay(last_service_placement, switch_service_placement, sprs)
        if switch_t < t:
            # not switch service
            print("not switch")
            index.append(0)
            sprs.update_trace(time_slot=t - 1)
            sprs.request_schedule_stage(switch_service_placement)
            no_switch_delay.append(sprs.final_delay)


if __name__ == '__main__':
    online_switch(beta=5)
    print(no_switch_delay, switch_delay, sep='\n')
    print(index)
